package com.wjk.kylin.modules.system.dict.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wjk.kylin.core.common.redis.RedisRepository;
import com.wjk.kylin.core.constant.CommonConstant;
import com.wjk.kylin.core.constant.Constants;
import com.wjk.kylin.core.exception.BusinessException;
import com.wjk.kylin.modules.system.dict.entity.DictValue;
import com.wjk.kylin.modules.system.dict.mapper.DictValueMapper;
import com.wjk.kylin.modules.system.dict.service.IDictValueService;
import com.wjk.kylin.modules.system.vo.ListSelectVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;


/**
 * <p>
 *  字典数据表 服务实现类
 * </p>
 *
 * @author wangjkui
 * @since 2020-06-07
 */
@Service
@Transactional(readOnly=true)
public class DictValueServiceImpl extends ServiceImpl<DictValueMapper, DictValue> implements IDictValueService {
    @Autowired
    private RedisRepository redisRepository;

    @Override
    public IPage<DictValue> findPage(Page<DictValue> page, DictValue dictValue) {
        return baseMapper.findPage(page,dictValue);
    }

    @Override
    @Transactional(readOnly=false)
    public boolean save(DictValue dictValue) {
        //1.判断value是否已经存在
        QueryWrapper<DictValue> wrapper = new QueryWrapper<>();
        wrapper.eq("value", dictValue.getValue());
        wrapper.eq("type", dictValue.getType());//当前类型中的value是否有相同的
        int count = this.count(wrapper);
        if(count > 0){
            throw new BusinessException("字典键值已存在，请重新添加");
        }

        dictValue.preInsert();
        boolean flag = super.save(dictValue);

        //删除缓存
        redisRepository.del(Constants.CACHE_DICT_REDIS_KEY + dictValue.getType());

        return flag;
    }

    @Override
    @Transactional(readOnly=false)
    public boolean update(DictValue dictValue) {
        //1.判断value是否已经存在
        QueryWrapper<DictValue> wrapper = new QueryWrapper<>();
        wrapper.eq("value", dictValue.getValue());
        wrapper.eq("type", dictValue.getType());//当前类型中的value是否有相同的
        wrapper.ne("id", dictValue.getId());
        int count = this.count(wrapper);
        if(count > 0){
            throw new BusinessException("字典键值已存在，请重新修改");
        }

        //2.修改数据库
        dictValue.preUpdate();

        boolean flag = super.updateById(dictValue);

        //1.删除缓存
        redisRepository.del(Constants.CACHE_DICT_REDIS_KEY + dictValue.getType());

        return flag;
    }

    @Override
    @Transactional(readOnly=false)
    public boolean deleteByIds(String[] dictValueIds) {
        List<String> ids = Arrays.asList(dictValueIds);

        List<DictValue> list = super.listByIds(ids);

        //2.删除数据库
        boolean flag = super.removeByIds(ids);

        //1.删除缓存
        list.forEach(dictValue ->{
            redisRepository.del(Constants.CACHE_DICT_REDIS_KEY + dictValue.getType());
        });

        return flag;
    }

    @Override
    public List<ListSelectVO> getDictValueByType(String dictType) {

        String redisKey = Constants.CACHE_DICT_REDIS_KEY + dictType;

        //1.判断缓存中是否存在
        if(redisRepository.exists(redisKey)){

            return JSONObject.parseArray(redisRepository.get(redisKey), ListSelectVO.class);//json转换为list集合
        }

        //2.查询数据库
        QueryWrapper<DictValue> wrapper = new QueryWrapper<>();
        wrapper.eq("type", dictType);
//        wrapper.eq("status", CommonConstant.DataStatus.OK.getCode()); TODO 只有正常才能查询使用
        wrapper.orderByAsc("sort");

        List<DictValue> list = this.list(wrapper);

        //3.数据转换
        List<ListSelectVO> listSelect = list.stream().map(ListSelectVO::new).collect(Collectors.toList());

        //4.加入缓存
        redisRepository.set(redisKey, JSONObject.toJSONString(listSelect));//json字符串

        return listSelect;

    }

    @Override
    @Transactional(readOnly=false)
    public void updateTypeByType(String newType, String oldType) {
        UpdateWrapper<DictValue> wrapper = new UpdateWrapper<>();

        wrapper.set("type",newType);
        wrapper.eq("type", oldType);

        super.update(wrapper);
    }

    @Override
    @Transactional(readOnly=false)
    public void deleteByType(List<String> types) {

        //2.删除数据库
        QueryWrapper<DictValue> wrapper = new QueryWrapper<>();
        wrapper.in("type", types);

        super.remove(wrapper);

        //1.删除缓存
        types.forEach(type->{
            redisRepository.del(Constants.CACHE_DICT_REDIS_KEY + type);
        });

    }
}
